"""Job资源Markdown写入器模块"""

from typing import Dict, Any, List
import yaml
from src.writers.base import Writer
from src.utils.markdown_builder import MarkdownBuilder

class JobWriter(Writer):
    """
    Job资源Markdown写入器
    负责将提取的Job资源信息写入Markdown文件
    """
    
    def write(self, data: Dict[str, Any], output_path: str) -> None:
        """
        将提取的Job信息写入Markdown
        
        Args:
            data: 提取的Job信息
            output_path: 输出文件路径
        """
        if not data or data.get("kind") != "Job":
            self.logger.warning(f"无效的Job数据: {data.get('name', '未知')}")
            return
        
        # 创建Markdown构建器
        md = self.create_markdown_builder()
        
        # 收集节标题，用于生成目录
        sections = ["基本信息", "作业配置", "状态", "容器", "存储卷"]
        
        # 标题
        md.header(f"Job: {data.get('name', '未知')}", 1)
        
        # 命名空间
        md.bold("命名空间:").text(f" {data.get('namespace', 'default')}").newline(2)
        
        # 目录
        if len(sections) > 3:  # 只有当节较多时才添加目录
            md.toc(sections)
        
        # 基本信息
        self._write_basic_info(md, data)
        
        # 作业配置
        self._write_job_config(md, data)
        
        # 状态信息
        self._write_status(md, data)
        
        # 容器信息
        self._write_containers(md, data)
        
        # 卷信息
        self._write_volumes(md, data)
        
        # 生成Markdown文件
        self.write_markdown(md, output_path)
    
    def _write_basic_info(self, md: MarkdownBuilder, data: Dict[str, Any]) -> None:
        """
        写入基本信息
        
        Args:
            md: Markdown构建器
            data: Job数据
        """
        md.header("基本信息", 2)
        
        # 基本元数据表
        basic_info = {
            "名称": data.get("name", ""),
            "命名空间": data.get("namespace", "default"),
            "创建时间": data.get("creation_timestamp", "")
        }
        
        md.dict_table(basic_info)
        
        # 标签和注解
        if data.get("labels"):
            md.header("标签", 3)
            md.dict_table(data.get("labels", {}))
        
        if data.get("annotations"):
            md.header("注解", 3)
            md.dict_table(data.get("annotations", {}))
    
    def _write_job_config(self, md: MarkdownBuilder, data: Dict[str, Any]) -> None:
        """
        写入Job配置信息
        
        Args:
            md: Markdown构建器
            data: Job数据
        """
        md.header("作业配置", 2)
        
        spec = data.get("spec", {})
        if not spec:
            md.paragraph("未提供作业配置")
            return
        
        job_config = {}
        
        # 完成数
        if "completions" in spec:
            job_config["需要完成的Pod数"] = spec.get("completions", 1)
            
        # 并行度
        if "parallelism" in spec:
            job_config["并行运行的Pod数"] = spec.get("parallelism", 1)
            
        # 激活截止期限秒数
        if "active_deadline_seconds" in spec:
            deadline = spec.get("active_deadline_seconds", 0)
            job_config["作业超时时间"] = f"{deadline}秒"
            
        # 重试次数
        if "backoff_limit" in spec:
            job_config["重试次数上限"] = spec.get("backoff_limit", 6)
            
        # 完成模式
        if "completion_mode" in spec:
            mode = spec.get("completion_mode", "NonIndexed")
            mode_map = {
                "NonIndexed": "非索引模式",
                "Indexed": "索引模式"
            }
            job_config["完成模式"] = mode_map.get(mode, mode)
            
        # 成功完成歷史保留限制
        if "ttl_seconds_after_finished" in spec:
            ttl = spec.get("ttl_seconds_after_finished", 0)
            job_config["作业完成后保留时间"] = f"{ttl}秒"
            
        # Pod失败策略
        if "pod_failure_policy" in spec:
            job_config["Pod失败策略"] = "已配置"
            
        # 重启策略
        pod_spec = data.get("template", {}).get("spec", {})
        if "restart_policy" in pod_spec:
            policy = pod_spec.get("restart_policy", "")
            policy_map = {
                "Never": "永不重启",
                "OnFailure": "失败时重启",
                "Always": "总是重启"
            }
            job_config["重启策略"] = policy_map.get(policy, policy)
        
        md.dict_table(job_config)
        
        # 如果有索引完成模式，添加更多细节
        if spec.get("completion_mode") == "Indexed" and "completion_index" in spec:
            md.header("索引配置", 3)
            md.dict_table({"索引范围": f"0-{spec.get('completions') - 1}"})
    
    def _write_status(self, md: MarkdownBuilder, data: Dict[str, Any]) -> None:
        """
        写入状态信息
        
        Args:
            md: Markdown构建器
            data: Job数据
        """
        md.header("状态", 2)
        
        status = data.get("status", {})
        if not status:
            md.paragraph("未提供状态信息")
            return
        
        status_info = {}
        
        # 开始/完成时间
        if "start_time" in status:
            status_info["开始时间"] = status.get("start_time", "")
            
        if "completion_time" in status:
            status_info["完成时间"] = status.get("completion_time", "")
            
        # Pod统计
        status_info["活跃Pod数"] = status.get("active", 0)
        status_info["成功Pod数"] = status.get("succeeded", 0)
        status_info["失败Pod数"] = status.get("failed", 0)
            
        # 条件
        conditions = status.get("conditions", [])
        if conditions:
            for condition in conditions:
                cond_type = condition.get("type", "")
                status_value = condition.get("status", "")
                if cond_type == "Complete" and status_value == "True":
                    status_info["作业状态"] = "已完成"
                elif cond_type == "Failed" and status_value == "True":
                    status_info["作业状态"] = "已失败"
                    if "reason" in condition:
                        status_info["失败原因"] = condition.get("reason", "")
                        status_info["失败消息"] = condition.get("message", "")
        
        md.dict_table(status_info)
    
    def _write_containers(self, md: MarkdownBuilder, data: Dict[str, Any]) -> None:
        """
        写入容器信息
        
        Args:
            md: Markdown构建器
            data: Job数据
        """
        md.header("容器", 2)
        
        # 获取容器信息
        pod_spec = data.get("template", {}).get("spec", {})
        containers = pod_spec.get("containers", [])
        
        if not containers:
            md.paragraph("未定义容器")
            return
        
        # 遍历每个容器
        for i, container in enumerate(containers):
            container_name = container.get("name", f"container-{i+1}")
            md.header(f"容器 {i+1}: {container_name}", 3)
            
            # 基本容器信息
            with md.list() as lst:
                lst.item(f"**镜像:** {container.get('image', '未指定')}")
                
                if "image_pull_policy" in container:
                    lst.item(f"**镜像拉取策略:** {container.get('image_pull_policy')}")
                    
                if "command" in container:
                    command = " ".join(container.get("command", []))
                    lst.item(f"**命令:** `{command}`")
                    
                if "args" in container:
                    args = " ".join(container.get("args", []))
                    lst.item(f"**参数:** `{args}`")
            
            # 环境变量
            if container.get("env"):
                md.header("环境变量", 4)
                
                headers = ["名称", "值", "来源"]
                rows = []
                
                for env in container.get("env", []):
                    name = env.get("name", "")
                    value = env.get("value", "")
                    value_from = ""
                    
                    if "value_from" in env:
                        value_from_dict = env.get("value_from", {})
                        if "configMapKeyRef" in value_from_dict:
                            cm_ref = value_from_dict.get("configMapKeyRef", {})
                            value_from = f"ConfigMap: {cm_ref.get('name', '')}.{cm_ref.get('key', '')}"
                        elif "secretKeyRef" in value_from_dict:
                            secret_ref = value_from_dict.get("secretKeyRef", {})
                            value_from = f"Secret: {secret_ref.get('name', '')}.{secret_ref.get('key', '')}"
                        elif "fieldRef" in value_from_dict:
                            field_ref = value_from_dict.get("fieldRef", {})
                            value_from = f"Field: {field_ref.get('field_path', '')}"
                    
                    rows.append([name, value, value_from])
                
                md.table(headers, rows)
                
            # 资源限制
            if container.get("resources"):
                md.header("资源配置", 4)
                
                resources = container.get("resources", {})
                requests = resources.get("requests", {})
                limits = resources.get("limits", {})
                
                if requests:
                    md.bold("请求:").newline()
                    
                    with md.list() as lst:
                        for resource_type, value in requests.items():
                            lst.item(f"{resource_type}: {value}")
                    
                    md.newline()
                
                if limits:
                    md.bold("限制:").newline()
                    
                    with md.list() as lst:
                        for resource_type, value in limits.items():
                            lst.item(f"{resource_type}: {value}")
                    
                    md.newline()
            
            # 卷挂载
            if container.get("volume_mounts"):
                md.header("卷挂载", 4)
                
                headers = ["名称", "挂载路径", "只读"]
                rows = []
                
                for mount in container.get("volume_mounts", []):
                    name = mount.get("name", "")
                    path = mount.get("mount_path", "")
                    read_only = "是" if mount.get("read_only", False) else "否"
                    
                    rows.append([name, path, read_only])
                
                md.table(headers, rows)
    
    def _write_volumes(self, md: MarkdownBuilder, data: Dict[str, Any]) -> None:
        """
        写入卷信息
        
        Args:
            md: Markdown构建器
            data: Job数据
        """
        md.header("存储卷", 2)
        
        # 获取卷信息
        pod_spec = data.get("template", {}).get("spec", {})
        volumes = pod_spec.get("volumes", [])
        
        if not volumes:
            md.paragraph("未定义存储卷")
            return
            
        # 遍历每个卷
        for i, volume in enumerate(volumes):
            volume_name = volume.get("name", f"volume-{i+1}")
            md.header(f"卷 {i+1}: {volume_name}", 3)
            
            # 确定卷类型并格式化
            if "config_map" in volume:
                config_map = volume.get("config_map", {})
                md.bold("类型:").text(" ConfigMap").newline()
                md.bold("ConfigMap名称:").text(f" {config_map.get('name', '')}").newline()
                
                if "items" in config_map:
                    md.newline().bold("配置项:").newline()
                    
                    with md.list() as lst:
                        for item in config_map.get("items", []):
                            key = item.get("key", "")
                            path = item.get("path", "")
                            lst.item(f"{key} -> {path}")
            
            elif "secret" in volume:
                secret = volume.get("secret", {})
                md.bold("类型:").text(" Secret").newline()
                md.bold("Secret名称:").text(f" {secret.get('name', '')}").newline()
                
                if "items" in secret:
                    md.newline().bold("配置项:").newline()
                    
                    with md.list() as lst:
                        for item in secret.get("items", []):
                            key = item.get("key", "")
                            path = item.get("path", "")
                            lst.item(f"{key} -> {path}")
            
            elif "empty_dir" in volume:
                empty_dir = volume.get("empty_dir", {})
                md.bold("类型:").text(" emptyDir").newline()
                
                if "medium" in empty_dir:
                    md.bold("存储介质:").text(f" {empty_dir.get('medium', 'Memory')}").newline()
                
                if "size_limit" in empty_dir:
                    md.bold("大小限制:").text(f" {empty_dir.get('size_limit', '')}").newline()
            
            elif "persistent_volume_claim" in volume:
                pvc = volume.get("persistent_volume_claim", {})
                md.bold("类型:").text(" PersistentVolumeClaim").newline()
                md.bold("PVC名称:").text(f" {pvc.get('claim_name', '')}").newline()
                md.bold("只读:").text(f" {'是' if pvc.get('read_only', False) else '否'}").newline()
            
            elif "host_path" in volume:
                host_path = volume.get("host_path", {})
                md.bold("类型:").text(" hostPath").newline()
                md.bold("路径:").text(f" {host_path.get('path', '')}").newline()
                
                if "type" in host_path:
                    type_map = {
                        "": "未指定",
                        "DirectoryOrCreate": "目录或创建",
                        "Directory": "目录",
                        "FileOrCreate": "文件或创建",
                        "File": "文件",
                        "Socket": "套接字",
                        "CharDevice": "字符设备",
                        "BlockDevice": "块设备"
                    }
                    type_value = host_path.get("type", "")
                    md.bold("类型:").text(f" {type_map.get(type_value, type_value)}").newline()
            
            else:
                # 处理其他可能的卷类型
                volume_type = next(iter(volume.keys()), "unknown")
                if volume_type != "name":
                    md.bold("类型:").text(f" {volume_type}").newline()
                    md.bold("详细信息:").newline()
                    
                    with md.code_block("yaml"):
                        md.text(yaml.dump(volume, default_flow_style=False))